/**
 *	(C) 2014 Yuanjj
 *
 *	define tunnel objects manager class
 *
 *	histroy
 * 		2014-08-07	yuanjj	- create the file
 */

#include "tunnel.h"
#include "errorcode.h"
#include "routine/global.h"

cls_tunnel::cls_tunnel()
{
    m_que_array[CL_DB]	= &m_que_db;
    m_que_array[CL_NET]	= &m_que_net;
    m_que_array[CL_UI]	= &m_que_ui;
}

cls_tunnel::~cls_tunnel()
{
    release();
}

/**
 *	initialize the tunnel object
 *
 * 	return
 * 		==	0	successful
 * 		!=	0	errorcode
 */
pem_error_t	cls_tunnel::instance()
{
    pem_error_t		res;

    res = m_que_db.instance( 1 << 20 );
    if ( 0 != res )
    {
        g_log.write( LOG_ERR, "tunnel", "data base queue initialize failed(size = %d)[error = 0x%x]", 1<<20, res );
        goto EXIT;
    }

    res = m_que_net.instance( 1 << 20 );
    if ( 0 != res )
    {
        g_log.write( LOG_ERR, "tunnel", "net work queue initialize failed(size = %d)[error = 0x%x]", 1<<20, res );
        goto EXIT;
    }

    res = m_que_ui.instance( 1 << 20 );
    if ( 0 != res )
    {
        g_log.write( LOG_ERR, "tunnel", "ui queue initialize failed(size = %d)[error = 0x%x]", 1<<20, res );
        goto EXIT;
    }

EXIT:
    return res;
}

/**
 *	releas the tunnel object
 */
pem_void_t cls_tunnel::release()
{
    pem_s32_t		i;

    for ( i = 0; i < CL_ALL; i++ )
        m_que_array[i]->release();
}

/**
 *	put data into the special tunnel
 *
 * 	@type		[in] the tunnel type ( CL_DB, CL_NET or CL_UI )
 * 	@pdata		[in] the data buffer
 * 	@size		[in] the data size
 * 	@flag		[in] the way to put into the tunnel
 *
 * 	return
 * 		==	0	successful
 * 		!=	0	errorcode
 */
pem_error_t	cls_tunnel::putdata( pem_u8_t type, pem_s8_t* pdata, pem_u32_t size, pem_s32_t flag )
{
    pem_error_t		res;

    if ( type < CL_ALL )
        res = m_que_array[type]->putdata( pdata, size, flag );
    else
        res = BUILD_ERRORCODE( 0, PEM_TUNNEL_TYPE );

    return res;
}

/**
 *	get data from the speical tunnel
 *
 * 	@type		[in] the tunnel type ( CL_DB, CL_NET or CL_UI )
 * 	@pdata		[out] the data buffer that will load the data
 * 	@size		[in] the data size that want to be load
 *
 * 	return
 * 		==	0	successful
 * 		!=	0	errorcode
 */
pem_error_t	cls_tunnel::getdata( pem_u8_t type, pem_s8_t* pdata, pem_u32_t size )
{
    pem_error_t		res;

    if ( type < CL_ALL )
        res = m_que_array[type]->getdata( pdata, size );
    else
        res = BUILD_ERRORCODE( 0, PEM_TUNNEL_TYPE );

    return res;
}

/**
 *	clear up special tunnel
 *
 * 	@type		[in] the tunnel type (CL_DB, CL_NET, CL_UI or CL_ALL, if it is CL_ALL, clear all tunnel)
 *
 * 	return
 * 		==	0	successful
 * 		!=	0	errorcode
 *
 * 	remark:
 * 		if the type is "CL_ALL", it may make some errors, but the function can only return the last errorcode.
 * Each error will be record into log file
 */
pem_error_t cls_tunnel::setempty( pem_u8_t type )
{
    pem_error_t		final_res;
    pem_error_t		res;
    pem_error_t		i;

    if ( CL_ALL > type )
    {
        final_res = m_que_array[type]->setempty();
        if ( PEM_OK != final_res )
            g_log.write( LOG_WARN, "tunnel", "clear up tunnel(%d) failed[error = 0x%x]", type, final_res );
    }
    else if ( CL_ALL == type )
    {
        for ( i = 0; i < CL_ALL; i++ )
        {
            res = m_que_array[i]->setempty();
            if ( PEM_OK != res )
            {
                final_res = res;
                g_log.write( LOG_WARN, "tunnel", "clear up tunnel(%d) failed[error = 0x%x]", i, res );
            }
        }
    }
    else
    {
        final_res = BUILD_ERRORCODE( 0, PEM_TUNNEL_TYPE );
        if ( PEM_OK != final_res )
            g_log.write( LOG_WARN, "tunnel", "clear up tunnel(%d) failed[error = 0x%x]", type, final_res );
    }

    return	final_res;
}
